/* XMLTileParser.fx
*  ----------------
*  INPUT:   Event name.
*  OUTPUT:  Group of tiles.
*
*Created on Apr 1, 2011, 15:11:01 PM
*/

package mythesis.controller;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
import java.lang.*;
import mythesis.tiles.character.*;
import mythesis.tiles.variable.*;
import javafx.scene.*;

var tileGroup = Group{};		// current list of tiles.
var eventName:String = "";		// name of event

public var numList:String[];
public var wordList:String[];
public var truthList:String[];
public var candidateList:String[];

public class XMLTileParser {
};

function getElementIndexByName():Integer
{
    if (eventName == "GameStarted")							{	return 0;	}
    else if (eventName == "DecidingOnMovement") 			{	return 1;	}
    else if (eventName == "MakingASuggestionOrAccusation")	{	return 2;	}
    else if (eventName == "ListeningToSuggestion")			{	return 3;	}
    else if (eventName == "DisprovingSuggestion") 			{	return 4;	}
    else													{   println("[XMLTileParser] Unknown event name:  {eventName}"); return 5;	}
}

public function getTileList(fileNumber:Number):Group
{
    // remove decimal point
	var fileNumString:String = fileNumber.toString();
	fileNumString = fileNumString.replace(".0", "");
	var fileNumInteger:Integer = java.lang.Integer.parseInt(fileNumString);
    
    var dbf:DocumentBuilderFactory = DocumentBuilderFactory.newInstance();
    try
    {
        var db:DocumentBuilder = dbf.newDocumentBuilder();
        //var doc:Document = db.parse(new FileInputStream("C:/Users/ncinco/Eclipse/workspace/ClueMeRemake/src/mythesis/test/SampleAI.xml"));
        var doc:Document = db.parse(new FileInputStream("CustomAI{fileNumInteger}.xml"));
        
        var root:Element = doc.getDocumentElement();
        //println("Root name : {root.getNodeName()}");
        
        var events = root.getElementsByTagName("event");
        //println("Number of events : {events.getLength()}\n\n");
        
        var id = getElementIndexByName();
        
        
        // get particular event only
        var el:Element  = {events.item(id) as Element};
        var type:String = el.getAttribute("type");
        //println(" Event name: {type}");
        
        // get all tiles
        var tiles:NodeList = el.getElementsByTagName("tile");
        //println(" # of tiles: {tiles.getLength()}");
        
        var numbers:NodeList = el.getElementsByTagName("number");
        var words:NodeList = el.getElementsByTagName("word");
        var truths:NodeList = el.getElementsByTagName("truth");
        var candidates:NodeList = el.getElementsByTagName("candidate");
        
        
        // find all variables
        for (j in [0..numbers.getLength()-1])
        {
           var elNum:Element      = {numbers.item(j) as Element};
           var elNumText:String   = elNum.getTextContent();
           insert elNumText into numList;
                
           //println(" @Number: {elNumText} ");
        }
        for (j in [0..words.getLength()-1])
        {
           var elWord:Element      = {words.item(j) as Element};
           var elWordText:String   = elWord.getTextContent();
           insert elWordText into wordList;
                
           //println(" @Word: {elWordText} ");
        }
        for (j in [0..truths.getLength()-1])
        {
           var elTruth:Element      = {truths.item(j) as Element};
           var elTruthText:String   = elTruth.getTextContent();
           insert elTruthText into truthList;
                
           //println(" @Truth: {elTruthText} ");
        }
        for (j in [0..candidates.getLength()-1])
        {
           var elCandidate:Element      = {candidates.item(j) as Element};
           var elCandidateText:String   = elCandidate.getTextContent();
           insert elCandidateText into candidateList;
                
           //println(" @Candidate: {elCandidateText} ");
        }
        
        // loop through all tiles
        for (j in [0..tiles.getLength()-1])
        {
            var ti:Element = {tiles.item(j) as Element};
            
            // get name and line
            var tileType:String     = ti.getAttribute("type");
            var lineNumber:String   = ti.getAttribute("line");
            var argList:NodeList    = ti.getElementsByTagName("arg");
            
            lineNumber = lineNumber.replace(".0", "");
            var lineNumberInteger:Integer = java.lang.Integer.parseInt(lineNumber);
            var lineNumberNumber:Number = {lineNumberInteger as Number};
            
            var arrArgText:String[]   = [];
            var arrArgDtype:String[]  = [];
            var arrArgDvalue:String[] = [];
            
            //print(" > line:{lineNumber} :: {tileType} ");
            for (k in [0..argList.getLength()-1])
            {
                var arg:Element      = {argList.item(k) as Element};
                var argText:String   = arg.getTextContent();
                var argDtype:String  = arg.getAttribute("dtype");
                var argDvalue:String = arg.getAttribute("dvalue");
                
                insert argText into arrArgText;
                insert argDtype into arrArgDtype;
                insert argDvalue into arrArgDvalue;
                
                //print(" [{argDtype}][{argDvalue}]({argText}) ");
            }
            addTile(tileType, lineNumberNumber, arrArgDtype, arrArgDvalue, arrArgText);
            
            //println("\n");
            
        }
    }
    catch (e:Exception)
    {
        println("[XMLTileParser.getTileList()] {e}");
    }
    return tileGroup;
}

// empties tile list
public function newTileList(e:String):Void
{
    eventName = e;
    numList = [];
    wordList = [];
    truthList = [];
    candidateList = [];
	for (i in [0..tileGroup.content.size()])
	{
	    delete tileGroup.content[i];
	}
}

// add tile to list
function addTile(ttype:String, pline:Integer, argDTypes:String[], argDValues:String[], argTexts:String[])
{
    var dtypes:Number[] = convertStringsToNumbers(argDTypes);
    var dvalues:Number[] = convertStringsToNumbers(argDValues);
    
    if (ttype == "Accuse")
    {
        var t = Accuse{};
	    t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "DisproveSuggestionWith")
    {
        var t = DisproveSuggestionWith{};
	    t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "GoTo")
    {
        var t = GoTo{};
	    t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "ListenToSuggestion")
    {
        var t = ListenToSuggestion{};
	    t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "RollDice")
    {
        var t = RollDice{};
	    t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Suggest")
    {
        var t = Suggest{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "TakeShortcut")
    {
        var t = TakeShortcut{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "BreakCondition")
    {
        var t = BreakCondition{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Decrease")
    {
        var t = Decrease{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Divide")
    {
        var t = Divide{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "EndCondition")
    {
        var t = EndCondition{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Falsify")
    {
        var t = Falsify{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "If")
    {
        var t = If{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Increase")
    {
        var t = Increase{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Multiply")
    {
        var t = Multiply{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Note")
    {
        var t = Note{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Raise")
    {
        var t = Raise{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Set")
    {
        var t = Set{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "Testify")
    {
        var t = Testify{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
    else if (ttype == "While")
    {
        var t = While{};
        t.line      = pline;
	    t.args      = argTexts;
	    t.dataType  = dtypes;
	    t.dataValue = dvalues;
	    insert t into tileGroup.content;
    }
	else
	{
	    println("[XMLTileParser.fx] UNKNOWN TTYPE = {ttype}.");
	}

    
	
}

function convertStringsToNumbers(s:String[])
{
    var n:Number[] = [];
    
    
    for (i in [0..s.size()])
    {
        if (s[i] == "0" or s[i] =="0.0"){		insert 0 into n;	}
        else if (s[i] == "1" or s[i] =="1.0"){	insert 1 into n;	}
        else if (s[i] == "2" or s[i] =="2.0"){	insert 2 into n;	}
        else if (s[i] == "3" or s[i] =="3.0"){	insert 3 into n;	}
        else if (s[i] == "4" or s[i] =="4.0"){	insert 4 into n;	}
    }
    return n;
} 